package com.zwps.biz.domain.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zwps.biz.domain.converter.LogMessageConverter;
import com.zwps.biz.domain.service.LogMessageService;
import com.zwps.biz.api.model.dto.log.message.SelectLogMessageDTO;
import com.zwps.biz.api.model.vo.log.message.SelectLogMessageVO;
import com.zwps.biz.dal.db.dao.LogMessageDAO;
import com.zwps.biz.dal.db.object.LogMessageDO;
import com.zwps.common.api.model.vo.PageInfoVO;
import com.zwps.common.core.enums.MessageTypeEnum;
import com.zwps.common.core.exception.ServeException;
import com.zwps.common.core.rabbitmq.message.LogMessage;
import com.zwps.common.core.service.CommonService;
import com.zwps.common.tool.enums.EnumConverter;

import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@AllArgsConstructor
@Service
@Slf4j
public class LogMessageServiceImpl implements LogMessageService, CommonService {

    private LogMessageDAO logDAO;

    private ObjectMapper objectMapper;

    @Override
    public void addLogMessage(LogMessage message) {
        LogMessageDO log = LogMessageConverter.INSTANCE.toLogMessageDO(message);
        if (log.getCreateTime() == null) {
            log.setCreateTime(LocalDateTime.now());
        }
        if (logDAO.insert(log) < 1) {
            throw new ServeException("添加日志消息失败");
        }
    }

    @Override
    public void addLogMessage(String message) {
        try {
            LogMessage logMessage = objectMapper.readValue(message, LogMessage.class);
            addLogMessage(logMessage);
        } catch (Exception e) {
            log.error("Unexpected error in ", e);
        }
    }

    @Override
    public void deleteLogMessage(ArrayList<Integer> ids) {
        logDAO.deleteBatchIds(ids);
    }

    @Override
    public PageInfoVO<SelectLogMessageVO> selectLogMessagePage(SelectLogMessageDTO dto) {
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        LambdaQueryWrapper<LogMessageDO> query = Wrappers.lambdaQuery(LogMessageDO.class);
        isNotEmptySetLike(query, LogMessageDO::getExchange, dto.getExchange());
        isNotEmptySetLike(query, LogMessageDO::getRouteKey, dto.getRouteKey());
        isNotEmptySetLike(query, LogMessageDO::getQueue, dto.getQueue());
        isNotEmptySetEq(query, LogMessageDO::getProjectId, dto.getProjectId());
        isNotEmptySetEq(query, LogMessageDO::getMessageSource, dto.getMessageSource());
        isNotEmptySetEq(query, LogMessageDO::getProcessStatus, dto.getProcessStatus());
        isNotEmptySetLe(query, LogMessageDO::getCreateTime, dto.getCreateTimeEnd());
        isNotEmptySetGe(query, LogMessageDO::getCreateTime, dto.getCreateTimeStart());
        query.orderByDesc(LogMessageDO::getId);
        if (StrUtil.isNotEmpty(dto.getMessageType())) {
            String[] messageTypes = dto.getMessageType().split(",");
            if (messageTypes.length == 1) {
                query.eq(LogMessageDO::getMessageType, dto.getMessageType());
            } else {
                query.in(LogMessageDO::getMessageType, Arrays.asList(messageTypes));
            }
        }

        List<LogMessageDO> list = logDAO.selectList(query);

        try (Page<LogMessageDO> page = (Page<LogMessageDO>) list) {
            ArrayList<SelectLogMessageVO> vos = new ArrayList<SelectLogMessageVO>();
            PageInfoVO<SelectLogMessageVO> pageInfo = new PageInfoVO<>(page.getPageNum(), page.getPageSize(),
                    page.getPages(), page.getTotal(), vos);
            LogMessageConverter converter = LogMessageConverter.INSTANCE;
            for (LogMessageDO logMessageDO : list) {
                SelectLogMessageVO vo = converter.toSelectLogMessageVO(logMessageDO);
                MessageTypeEnum type = EnumConverter.conver(MessageTypeEnum.values(), vo.getMessageType());
                if (type != null) {
                    vo.setMessageTypeName(type.getName());
                }
                vo.setProcessStatusName(vo.getProcessStatus() == 0 ? "成功" : "失败");
                vo.setMessageSourceName(vo.getMessageSource() == 1 ? "生成者" : "消费者");
                vos.add(vo);
            }
            return pageInfo;
        }
    }

}
